﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Itenso.TimePeriod;
using LogManager.Base.Data;
using LogManager.ViewModels;
using MvcContrib.Pagination;
using MvcContrib.Sorting;
using MvcContrib.UI.Grid;
using LogManager.Download;
using System.ServiceModel.Syndication;

namespace LogManager.Controllers
{
    public class LogController : BaseController
    {
        private readonly ILogService _logService;
        private readonly IServerService _serverService;
        private readonly IEventService _eventService;

        public LogController(IServerService serverService,ILogService logService, IEventService eventService)
        {
            _serverService = serverService;
            _logService = logService;
            _eventService = eventService;
        }

        /// <summary>
        /// Overview for all the logs
        /// </summary>
        /// <param name="sortOptions">Sort options for the logs</param>
        /// <param name="page">Page of the logs</param>
        /// <param name="count">Number of items per page</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Index(GridSortOptions sortOptions, int page = 1, int count = 20)
        {
            return View();
        }

        /// <summary>
        /// Returns a feed for the last events of log
        /// </summary>
        /// <param name="serverName">Name of the server</param>
        /// <param name="logName">Name of the log</param>
        /// <param name="count">Number of items</param>
        /// <returns></returns>
        [HttpGet]
        public FeedResult ListFeed(string serverName, string logName, int count = 20)
        {
            var events = _eventService.GetEvents(new TimeRange(DateTime.Now.AddDays(-30),DateTime.Now),serverName,logName)
                .OrderByDescending(e => e.TimeStamp).Take(count)
                .ToList();

            var items = events.Select(@event => new SyndicationItem(
                string.Format("Event with type {0} occured", @event.Type),
                @event.Message,
                new Uri(Url.Action("Detail", "Event", new { serverName, logName, id = @event.Id.Split('/')[3] }, Request.Url.Scheme))));

            var feed = new SyndicationFeed(
                logName,
                string.Format("A feed of events for log {0}.", logName),
                new Uri(Url.Action("Detail", "Log", new { serverName, logName }, Request.Url.Scheme)),
                items);

            return new FeedResult(new Rss20FeedFormatter(feed));
        }

        /// <summary>
        /// Get the details of a log
        /// </summary>
        /// <param name="serverName">Name of the server</param>
        /// <param name="logName">Name of the log</param>
        /// <param name="sortOptions">Sort options for the events</param>
        /// <param name="page">Page for the events</param>
        /// <param name="count">Number of items per page</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Detail(string serverName, string logName, GridSortOptions sortOptions,string view="List", int page = 1, int count = 20)
        {
            var model = new LogDetailViewModel()
                            {
                                Log = _logService.Get(serverName, logName),
                                View = view,
                                Views = new List<string> {"List", "ErrorEventList"},
                            };
            return View(model);
        }

        /// <summary>
        /// Get the navigation over servers
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ChildActionOnly]
        public ActionResult ListServerNavigation()
        {
            var servers = _serverService.All();
            return PartialView(servers);
        }

        /// <summary>
        /// Get the navigation over lgos of a server
        /// </summary>
        /// <param name="serverName">Name of the server</param>
        /// <returns></returns>
        [HttpGet]
        [ChildActionOnly]
        public ActionResult ListServerLogNavigation(string serverName)
        {
            var logs = _logService.All();
            return PartialView(logs);
        }

        /// <summary>
        /// List of the last written logs
        /// </summary>
        /// <param name="count">Number of latest logs to return</param>
        /// <returns>Partial view with the logs</returns>
        [HttpGet]
        public ActionResult List(GridSortOptions sortOptions, int page = 1,int count = 10)
        {
            var eventsPerLog = _eventService.GetEventsPerLog().ToList();
            var logs = _logService.All().ToList();

            foreach (var l in logs)
            {
                var epl = eventsPerLog.Where(x => x.LogName == l.LogName).SingleOrDefault();

                if (epl != null)
                {
                    l.LastWriteTime = epl.LastWriteTime;
                    l.Count = epl.Count;
                }
            }

            var model = new LogList
                            {
                                Logs = logs
                                    .AsPagination(page,count),
                                SortOptions = sortOptions
                            };
            return PartialView(model);
        }

        /// <summary>
        /// List of the logs ordered and sorted by their level
        /// </summary>
        /// <param name="count">Number of levels to return</param>
        /// <returns>Partial view with the logs</returns>
        [HttpGet]
        public ActionResult ListLevels(int count = 10)
        {
            var model = _eventService.GetLevelsPerLog();
            return PartialView(model);
        }
    }
}